#ifndef __TWINS_SPJ_STD_RUN_EVENT_HPP__
#define __TWINS_SPJ_STD_RUN_EVENT_HPP__

#include "base_event.hpp"
#include <filesystem>

namespace run_code_event_space {

struct twins_spj_std_run_event : base_event<twins_spj_std_run_event>  {
    template <class U>
    ProcessStatus execute_impl(run_code_context_t<U>& context, const string& inFile);
};

template <class U>
ProcessStatus twins_spj_std_run_event::execute_impl(run_code_context_t<U>& context, const string& inFile) {
    if (!context.judge_type.spjCompileOk) {
        return ProcessStatus{
                    .result = SPJFILE_COMPILE_ERROR,
                    .error = "spj not ready"
        };
    }
    if (!context.judge_type.stdCompileOk) {
        return ProcessStatus{
                    .result = STD_COMPILE_ERROR,
                    .error = "stdFile cannot run"
        };
    }

    const RuncodeParams& params = context.params;
    const U& judge_type = context.judge_type;
    auto in_file_path = std::filesystem::path(inFile);
    std::string outFile = (in_file_path.parent_path() / in_file_path.stem()).string() +  ".stdout";
    Log::instance().getOutput() << "inFile: " << inFile << endl;
    Log::instance().getOutput() << "outFile: " << outFile << endl;
    auto& [spjLang, spjCodeFile, spjBinFile, spjCompileStr, spjRunStr] = judge_type.spjCodeInfo;
    auto& [stdLang, stdCodeFile, stdBinFile, stdCompileStr, stdRunStr] = judge_type.stdCodeInfo;
    outFile = langMap["default"]->detect(outFile, params.spjCachePath);
    return general_execution_strategy::twins_process_run<false>(
                                            spjLang, spjRunStr, 
                                            stdLang, stdRunStr, 
                                            params.timeLimit, params.memoryLimit, 
                                            inFile, outFile,
                                            params.spjCachePath, params.spjCachePath);
}

}

#endif /* __TWINS_SPJ_STD_RUN_EVENT_HPP__ */
